package br.com.gkarian.mydesk.controller.financeiro;

import static br.com.caelum.vraptor.view.Results.json;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Put;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.ValidationMessage;
import br.com.gkarian.mydesk.anotacoes.RestritoUsuario;
import br.com.gkarian.mydesk.enums.TipoConta;
import br.com.gkarian.mydesk.model.financeiro.Banco;
import br.com.gkarian.mydesk.model.financeiro.ContaBancaria;
import br.com.gkarian.mydesk.services.financeiro.interfaces.FinanceiroServiceProxy;
import br.com.gkarian.mydesk.web.UsuarioWeb;

@Resource
@RestritoUsuario
public class ContaBancariaController {

	private static final Logger LOG = Logger.getLogger(ContaBancariaController.class);
	
	private Result result;
	private Validator validator;
	private UsuarioWeb usuarioWeb;
	private FinanceiroServiceProxy financeiroServiceProxy;
	
	public ContaBancariaController(Result result, Validator validator,
			UsuarioWeb usuarioWeb,
			FinanceiroServiceProxy financeiroServiceProxy) {
		this.result = result;
		this.validator = validator;
		this.usuarioWeb = usuarioWeb;
		this.financeiroServiceProxy = financeiroServiceProxy;
	}
	
	@Get("/financeiro/contaBancaria/cadastrar")
	public void cadastrarContaBancaria() {
		try {
			List<Banco> listBanco = financeiroServiceProxy.listarBancos();
			result.include("listTipoContas", gerarListaTipoConta());
			result.include("listBancos", listBanco);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarContaBancaria();
		}
	}

	@Post("/financeiro/contaBancaria/cadastrando")
	public void cadastrar(ContaBancaria contaBancaria, Integer bancoId) {
		validator.validate(contaBancaria);
		validator.onErrorRedirectTo(this).cadastrarContaBancaria();
		
		try {
			contaBancaria = financeiroServiceProxy.cadastrarContaBancaria(contaBancaria, bancoId, usuarioWeb.getLogado());
			result.redirectTo(this).cadastrarContaBancaria();
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarContaBancaria();
		}
	}

	@Get("/financeiro/contaBancaria/listar")
	public void listarContasBancarias() {
		try {
			List<ContaBancaria> listaContasBancarias = financeiroServiceProxy.listarContasBancarias(usuarioWeb.getLogado());
			result.include("listContasBancarias", listaContasBancarias);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarContaBancaria();
		}
	}
	
	@Delete("/financeiro/contaBancaria/{id}/remover")
	public void remover(Integer id) {
		try {
			financeiroServiceProxy.removerContaBancaria(id);
			result.redirectTo(this).listarContasBancarias();
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).cadastrarContaBancaria();
		}
	}
	
	@Get("/financeiro/contaBancaria/{id}/editar")
	public void editarContaBancaria(Integer id) {
		try {
			ContaBancaria contaBancaria = financeiroServiceProxy.carregarContaBancaria(id);
			List<Banco> listBancos = financeiroServiceProxy.listarBancos();
			result.include("contaBancaria", contaBancaria);
			result.include("listBancos", listBancos);
			result.include("listTipoContas", gerarListaTipoConta());
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).listarContasBancarias();
		}
	}
	
	@Put("/financeiro/contaBancaria/editando")
	public void editarContaBancaria(ContaBancaria contaBancaria, Integer bancoId) {
		validator.validate(contaBancaria);
		validator.onErrorRedirectTo(this).editarContaBancaria(contaBancaria.getId());
		
		try {
			financeiroServiceProxy.atualizarContaBancaria(contaBancaria, bancoId, usuarioWeb.getLogado());
			result.redirectTo(this).listarContasBancarias();
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			validator.add(new ValidationMessage("erro.inesperado", "error"));
			validator.onErrorRedirectTo(this).listarContasBancarias();
		}
	}
	
	@Get("/financeiro/contaBancaria/{id}/atualizarSaldo")
	public void atualizarSaldo(Integer id) throws Exception {
		try {
//			if (1 == 1)
//			throw new Exception("aaaa");
//			result.use(json()).withoutRoot().from("-51234").serialize();
			String novoSaldo = financeiroServiceProxy.atualizarSaldoContaBancaria(id, usuarioWeb.getLogado());
			result.use(json()).withoutRoot().from(novoSaldo).serialize();
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			String mensagem = "Ocorreu um erro inesperado!";
			result.use(json()).withoutRoot().from(mensagem).serialize(); //TODO: melhorar mensagem de retorno
		}
	}
	
	private List<String> gerarListaTipoConta() {
		List<String> listTipoConta = new ArrayList<String>();
		listTipoConta.add(TipoConta.CC.getNome());
		listTipoConta.add(TipoConta.PP.getNome());
		return listTipoConta;
	}
	
	
}
